﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OliveChess
{
    static class MoveHelper
    {
        private const Int16 MOVE_NONE = 0;
        private const Int16 MOVE_NULL = 65;
    
        /// A move needs 16 bits to be stored
        ///
        /// bit  0- 5: destination square (from 0 to 63)
        /// bit  6-11: origin square (from 0 to 63)
        /// bit 12-13: promotion piece type - 2 (from KNIGHT-2 to QUEEN-2)
        /// bit 14-15: special move flag: promotion (1), en passant (2), castle (3)
        ///
        /// Special cases are MOVE_NONE and MOVE_NULL. We can sneak these in because in
        /// any normal move destination square is always different from origin square
        /// while MOVE_NONE and MOVE_NULL have the same origin and destination square.

        // should return a square
        public static short From(Int16 move)
        {

        }

        // should return a square
        public static short To(Int16 move)
        {

        }

        public static Int16 MakeMove(int square1, int square2, Board b)
        {
            
        }

        public static Int16 MakeMove(int square1, int square2, Position p, char promotion)
        {
		    from = square1;
		    to = square2;
            piece = p.GetPiece(square1);
            cPiece = p.GetPiece(square2);
	        this.promotion = promotion;
	    }

        public static Int16 MakeMove(String move, Position p)
        {
            this.from = Square.Get(move.Substring(0, 2));
            this.to = Square.Get(move.Substring(2, 2));
            piece = p.GetPiece(from);
            cPiece = p.GetPiece(to);
            if (move.Length == 5)
            {
                promotion = move[4];
            }
            else
            {
                promotion = '0';
            }
        }

        	
	    public static String ToString(Int16 move) {
          Square from = from_sq(m);
          Square to = to_sq(m);
          string promotion;

          if (m == MOVE_NONE)
              return "(none)";

          if (m == MOVE_NULL)
              return "0000";

          if (is_castle(m) && !chess960)
              to = from + (file_of(to) == FILE_H ? Square(2) : -Square(2));

          if (is_promotion(m))
              promotion = char(tolower(piece_type_to_char(promotion_type(m))));

          return square_to_string(from) + square_to_string(to) + promotion;
	    }


        public static int EvalMoveBruitality(Int16 move)
        {
            // best captures first
            int captureEval = 2000*GetVal(move.cPiece);
            // lowest piece moved for capture first
            int pieceEval = 2000-GetVal(move.piece);
            return captureEval + pieceEval;
        }

        private static int GetVal(Piece piece)
        {
            switch (piece)
            {
                case Piece.W_KING:
                case Piece.B_KING:
                    return 1900;
                case Piece.W_QUEEN:
                case Piece.B_QUEEN:
                    return 900;
                case Piece.W_ROOK:
                case Piece.B_ROOK:
                    return 500;
                case Piece.W_BISHOP:
                case Piece.B_BISHOP:
                    return 300;
                case Piece.W_KNIGHT:
                case Piece.B_KNIGHT:
                    return 300;
                case Piece.W_PAWN:
                case Piece.B_PAWN:
                    return 90;
                case Piece.NO_PIECE:
                default:
                    return 0;
            }
        }

        public static bool IsCapture(Int16 move)
        {
            return (this.cPiece != Piece.NO_PIECE);
        }
    }
}
